package com.example.carrierapp.ui.view.banner;

import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.support.v4.view.MotionEventCompat;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.animation.Interpolator;
import android.widget.Scroller;

import java.lang.ref.WeakReference;
import java.lang.reflect.Field;


/**
 * 广告栏ViewPage，自动翻页，手动翻页
 */
public class ScorllPagerView extends ViewPager {
    private Handler handler; // 用于currentItem
    public static final int MANUAL_SCORLL_MSG = 0x0000;// 用户手动滑动
    public static final int AUTO_SCORLL_MSG = 0x0001;// 自动滑动
    public static final int SCORLL_DELAY = 1000; // handler延时
    public static final int AUTO_SCORLL_DELAY = 3000; // 自动滑动默认延时，3秒
    private static boolean touchStopAutoScorll = false;// 手势滑动时停止自动滑动
    private int adapterCount;// 图片数量
    private boolean isClick = false;// 判断点击事件
    private ScorllDurationScroller scroller = null; // 调整滚动完成时间
    private static long SCORLL_DURATION = 3; // 滚动动画完成时间
    private static long duration;// 自动滑动延时 默认3秒
    private OnPageScorllSelected onPageScorllSelected; //对外提供的pager点击和选中监听


    public interface OnPageScorllSelected {
        public void onScorllSelected(int position);

        public void onClickSelected(int position);
    }

    public ScorllPagerView(Context context) {
        super(context);
        init();
        setViewPagerScroller();
    }

    public ScorllPagerView(Context paramContext, AttributeSet paramAttributeSet) {
        super(paramContext, paramAttributeSet);
        init();
        setViewPagerScroller();
    }

    /**
     * 初始化设置
     */
    private void init() {
        duration = AUTO_SCORLL_DELAY; //设置滑动时间为默认时间3秒
        handler = new MyHandler(this);// 初始化handler
        //设置页面变化监听事件
        this.addOnPageChangeListener(new OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            }

            @Override
            public void onPageSelected(int position) {
                if (onPageScorllSelected != null) { //设置页面选中
                    onPageScorllSelected.onScorllSelected(position);
                }
            }

            @Override
            public void onPageScrollStateChanged(int state) {
            }
        });
    }

    /**
     * 设置页面滑动
     */
    private void setViewPagerScroller() {
        try {
            Field scrollerField = ViewPager.class.getDeclaredField("mScroller");
            scrollerField.setAccessible(true);
            Field interpolatorField = ViewPager.class.getDeclaredField("sInterpolator");
            interpolatorField.setAccessible(true);
            scroller = new ScorllDurationScroller(getContext(), (Interpolator) interpolatorField.get(null));
            scroller.setScorllDurationFactor(SCORLL_DURATION);
            scrollerField.set(this, scroller);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 设置自动滚动延时时间，默认3秒
     *
     * @param duration
     */
    @SuppressWarnings("static-access")
    public void setAutoScorllDuration(long duration) {
        this.duration = duration;
    }

    @Override
    public void setAdapter(PagerAdapter pagerAdapter) {
        super.setAdapter(pagerAdapter);
        PagerAdapter adapter = getAdapter();
        adapterCount = adapter == null ? 0 : adapter.getCount();
        if (adapterCount > 1) {
            setCurrentItem(1, false);
        }
        startAutoScorll(duration);
    }

    /**
     * 对外提供的pager点击和选中监听接口
     *
     * @param onPageScorllSelected
     */
    public void setOnPageScorllSelected(OnPageScorllSelected onPageScorllSelected) {
        this.onPageScorllSelected = onPageScorllSelected;
    }


    private float firstX = 0;// 按下时x坐标
    private float firstY = 0;// 按下时Y坐标
    private float scorllX = 0;// 滑动时x坐标
    private float scorllY = 0;// 滑动时Y坐标

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        scorllX = ev.getX();
        scorllY = ev.getY();
        final int currentItem = getCurrentItem();
        int action = MotionEventCompat.getActionMasked(ev);
//        if(action == MotionEvent.ACTION_CANCEL){
//            Log.i("TAG", "取消");
//            startScorll((SCORLL_DURATION / 2) * SCORLL_DELAY);
//            touchStopAutoScorll = false;
//            startAutoScorll(duration);
//        }
        if (action == MotionEvent.ACTION_DOWN) {
            firstX = scorllX;
            firstY = scorllY;
            touchStopAutoScorll = true;


        } else if (action == MotionEvent.ACTION_UP
                || action == MotionEvent.ACTION_CANCEL) {
            startScorll((SCORLL_DURATION / 2) * SCORLL_DELAY);
            touchStopAutoScorll = false;
            startAutoScorll(duration);
            if (action == MotionEvent.ACTION_UP) {
                if (Math.abs(firstY - ev.getY()) < 2 && Math.abs(firstX - ev.getX()) < 2) {
                    isClick = true;
                }
            }
            if (isClick) {
                if (onPageScorllSelected != null) {
                    int position;
                    if (currentItem == 0) {
                        position = adapterCount - 2;
                    } else if (currentItem == adapterCount - 1) {
                        position = 1;
                    } else {
                        position = currentItem;
                    }
                    onPageScorllSelected.onClickSelected(position);
                }
            }
        }

        if (Math.abs(firstX - scorllX) >= 5) {
            isClick = false;
        }
        if (adapterCount > 1) {
            if ((currentItem == 0 && firstX < scorllX)
                    || (currentItem == adapterCount - 1 && firstX > scorllX)) {
                startScorllNow();
            }
        }
        return super.dispatchTouchEvent(ev);
    }

    /**
     * 用户滑动首尾处理
     */
    private void ScorllChange() {
        int currentItem = getCurrentItem();
        if (currentItem == 0) {
            setCurrentItem(adapterCount - 2, false);
        } else if (currentItem == adapterCount - 1) {
            setCurrentItem(1, false);
        }
    }

    /**
     * 自动滑动首尾处理
     */
    private void autoScorllChange() {
        int currentItem = getCurrentItem();
        if (currentItem == 0) {
            setCurrentItem(adapterCount - 2, false);
        } else if (currentItem == adapterCount - 1) {
            setCurrentItem(1, false);
        } else {
            int item = currentItem++ >= adapterCount - 2 ? 1 : currentItem;
            setCurrentItem(item, true);
        }
    }

    /**
     * 开启手势滑动处理
     *
     * @param delay
     */
    private void startScorll(long delay) {
        sendScorllMessage(delay);
    }

    /**
     * 开启自动滑动处理
     *
     * @param delay
     */
    private void startAutoScorll(long delay) {
        sendAutoScorllMessage(delay);
    }

    /**
     * 无延时马上开启用户滑动处理
     */
    private void startScorllNow() {
        handler.removeMessages(MANUAL_SCORLL_MSG);
        handler.sendEmptyMessage(MANUAL_SCORLL_MSG);
    }

    private void sendScorllMessage(long delayTimeInMills) {
        handler.removeMessages(MANUAL_SCORLL_MSG);
        handler.sendEmptyMessageDelayed(MANUAL_SCORLL_MSG, delayTimeInMills);
    }

    private void sendAutoScorllMessage(long delayTimeInMills) {
        handler.removeMessages(AUTO_SCORLL_MSG);
        handler.sendEmptyMessageDelayed(AUTO_SCORLL_MSG, delayTimeInMills);
    }

    private static class MyHandler extends Handler {

        private final WeakReference<ScorllPagerView> autoScorllViewPager;

        public MyHandler(ScorllPagerView autoScorllViewPager) {
            this.autoScorllViewPager = new WeakReference<ScorllPagerView>(
                    autoScorllViewPager);
        }

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            ScorllPagerView pager = this.autoScorllViewPager.get();
            switch (msg.what) {
                case MANUAL_SCORLL_MSG:
                    if (pager != null) {
                        pager.ScorllChange();
                        pager.scroller.setScorllDurationFactor(SCORLL_DURATION);
                    }
                    break;
                case AUTO_SCORLL_MSG:
                    if (pager != null) {
                        if (!touchStopAutoScorll) {
                            pager.autoScorllChange();
                            pager.startAutoScorll(duration);
                            pager.scroller.setScorllDurationFactor(SCORLL_DURATION);
                        }
                    }
                    break;
                default:
                    break;
            }
        }
    }

    public class ScorllDurationScroller extends Scroller {
        private double slideFactor = 1;

        public ScorllDurationScroller(Context context) {
            super(context);
        }

        public ScorllDurationScroller(Context context, Interpolator interpolator) {
            super(context, interpolator);
        }

        public void setScorllDurationFactor(double slideFactor) {
            this.slideFactor = slideFactor;
        }

        @Override
        public void startScroll(int startX, int startY, int dx, int dy, int duration) {
            super.startScroll(startX, startY, dx, dy, (int) (duration * slideFactor));
        }
    }
}


